#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#include "gui/gui.h"

typedef struct ItemViewData
{
    ImageView *iconView;
    Layout *layout2;
    TextView *nameView;
    TextView *infoView;
    const GUI_Texture *icon_tex;
    const char *name_text;
    const char *info_text;
    uint32_t icon_tint_color;
    uint32_t name_text_color;
    uint32_t info_text_color;
} ItemViewData;

#define ITEMVIEW_CHILD_MARGIN 4

static int ItemViewDestroyData(ItemViewData *data)
{
    if (!data)
        return -1;

    free(data);
    return 0;
}

int ItemViewSetIconTexture(ItemView *itemView, const GUI_Texture *texture)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    int ret = ImageViewSetTexture(itemData->iconView, texture);
    if (texture && ret >= 0)
        ImageViewSetVisibility(itemData->iconView, TYPE_LAYOUT_VISIBILITY_VISIBLE);
    else
        ImageViewSetVisibility(itemData->iconView, TYPE_LAYOUT_VISIBILITY_GONE);

    return ret;
}

const GUI_Texture *ItemViewGetIconTexture(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return NULL;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return ImageViewGetTexture(itemData->iconView);
}

int ItemViewSetIconTintColor(ItemView *itemView, uint32_t color)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return ImageViewSetTintColor(itemData->iconView, color);
}

uint32_t ItemViewGetIconTintColor(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return 0;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return ImageViewGetTintColor(itemData->iconView);
}

int ItemViewSetNameText(ItemView *itemView, const char *text)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    int ret = TextViewSetText(itemData->nameView, text ? text : "");

    return ret;
}

const char *ItemViewGetNameText(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return NULL;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewGetText(itemData->nameView);
}

int ItemViewSetNameTextColor(ItemView *itemView, uint32_t color)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewSetTextColor(itemData->nameView, color);
}

uint32_t ItemViewGetNameTextColor(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return 0;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewGetTextColor(itemData->nameView);
}

int ItemViewSetNameTextScollEnabled(ItemView *itemView, int enabled)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewSetTextScollEnabled(itemData->nameView, enabled);
}

int ItemViewIsNameTextScollEnabled(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return 0;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewIsTextScollEnabled(itemData->nameView);
}

int ItemViewSetInfoText(ItemView *itemView, const char *text)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    int ret = TextViewSetText(itemData->infoView, text);
    if (text && ret >= 0)
        TextViewSetVisibility(itemData->infoView, TYPE_LAYOUT_VISIBILITY_VISIBLE);
    else
        TextViewSetVisibility(itemData->infoView, TYPE_LAYOUT_VISIBILITY_GONE);

    return ret;
}

const char *ItemViewGetInfoText(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return NULL;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewGetText(itemData->infoView);
}

int ItemViewSetInfoTextColor(ItemView *itemView, uint32_t color)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewSetTextColor(itemData->infoView, color);
}

uint32_t ItemViewGetInfoTextColor(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return 0;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewGetTextColor(itemData->infoView);
}

int ItemViewSetInfoTextScollEnabled(ItemView *itemView, int enabled)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewSetTextScollEnabled(itemData->infoView, enabled);
}

int ItemViewIsInfoTextScollEnabled(ItemView *itemView)
{
    if (!itemView || !itemView->viewdata)
        return 0;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    return TextViewIsTextScollEnabled(itemData->infoView);
}

int ItemViewMeasure(ItemView *itemView)
{
    return LayoutMeasure((Layout *)itemView);
}

int ItemViewDraw(ItemView *itemView)
{
    return LayoutDraw((Layout *)itemView);
}

int ItemViewFocusChange(ItemView *itemView, int focused)
{
    if (!itemView || !itemView->viewdata)
        return -1;

    ItemViewData *itemData = (ItemViewData *)itemView->viewdata;
    TextViewSetFocus(itemData->nameView, focused);

    return 0;
}

int ItemViewInit(ItemView *itemView)
{
    if (!itemView)
        return -1;

    memset(itemView, 0, sizeof(ItemView));

    Layout *layout = (Layout *)itemView;

    if (LayoutInit(layout) < 0)
        return -1;

    layout->onFinish = ItemViewDestroy; // 重定义onFinish为ItemViewDestroy，需要销毁ItemView的viewdata

    layout->viewdata = calloc(1, sizeof(ItemViewData));
    if (!layout->viewdata)
        goto FAILED;

    ItemViewData *itemData = (ItemViewData *)layout->viewdata;

    LayoutSetLayoutSize(layout, TYPE_LAYOUT_SIZE_WRAP_CONTENT, TYPE_LAYOUT_SIZE_WRAP_CONTENT);
    LayoutSetOrientation(layout, TYPE_LAYOUT_ORIENTATION_HORIZONTAL);
    LayoutSetGravity(layout, TYPE_LAYOUT_GRAVITY_CENTER_VERTICAL);
    layout->onFocusChange = ItemViewFocusChange;

    itemData->iconView = NewImageView();
    if (!itemData->iconView)
        goto FAILED;
    int icon_layout_h = GUI_GetLineHeight() * 2;
    ImageViewSetLayoutSize(itemData->iconView, icon_layout_h, icon_layout_h);
    ImageViewSetLayoutMargin(itemData->iconView, 0, ITEMVIEW_CHILD_MARGIN, 0, 0);
    ImageViewSetScaleType(itemData->iconView, TYPE_IMAGE_SCALE_FIT_CENTER_INSIDE);
    ImageViewSetVisibility(itemData->iconView, TYPE_LAYOUT_VISIBILITY_GONE);
    LayoutAddView(layout, itemData->iconView);

    itemData->layout2 = NewLayout();
    if (!itemData->layout2)
        goto FAILED;
    LayoutSetLayoutSize(itemData->layout2, TYPE_LAYOUT_SIZE_WRAP_CONTENT, TYPE_LAYOUT_SIZE_WRAP_CONTENT);
    LayoutSetOrientation(itemData->layout2, TYPE_LAYOUT_ORIENTATION_VERTICAL);
    LayoutAddView(layout, itemData->layout2);

    itemData->nameView = NewTextView();
    if (!itemData->nameView)
        goto FAILED;
    TextViewSetLayoutSize(itemData->nameView, TYPE_LAYOUT_SIZE_WRAP_CONTENT, TYPE_LAYOUT_SIZE_WRAP_CONTENT);
    TextViewSetSingleLine(itemData->nameView, 1);
    TextViewSetText(itemData->nameView, ""); // 设置空字符占个高度
    LayoutAddView(itemData->layout2, itemData->nameView);

    itemData->infoView = NewTextView();
    if (!itemData->infoView)
        goto FAILED;
    TextViewSetLayoutSize(itemData->infoView, TYPE_LAYOUT_SIZE_WRAP_CONTENT, TYPE_LAYOUT_SIZE_WRAP_CONTENT);
    TextViewSetSingleLine(itemData->infoView, 1);
    TextViewSetVisibility(itemData->infoView, TYPE_LAYOUT_VISIBILITY_GONE);
    LayoutAddView(itemData->layout2, itemData->infoView);

    return 0;

FAILED:
    ItemViewDeinit(itemView);
    return -1;
}

int ItemViewDeinit(ItemView *itemView)
{
    if (!itemView)
        return -1;

    ItemViewDestroyData((ItemViewData *)itemView->viewdata);
    LayoutDeinit((Layout *)itemView);
    memset(itemView, 0, sizeof(ItemView));

    return 0;
}

ItemView *NewItemView()
{
    ItemView *itemView = (ItemView *)malloc(sizeof(ItemView));
    if (!itemView)
        return NULL;

    if (ItemViewInit(itemView) < 0)
    {
        free(itemView);
        return NULL;
    }

    return itemView;
}

int ItemViewDestroy(ItemView *itemView)
{
    if (!itemView)
        return -1;

    if (itemView->dont_free)
        return 0;

    ItemViewDestroyData((ItemViewData *)itemView->viewdata);
    LayoutDeinit((Layout *)itemView);
    free(itemView);

    return 0;
}
